#include "Generate_C_std.h"
#include "Pattern_assign_var.h"

class Pattern_assign_expr_new : public Pattern_assign_var
{
public:
	Expr* rhs_pattern()
	{
		rhs = new Wildcard<New>;
		return rhs;
	}
 
	void generate_code(Generate_C* gen)
	{
		CLASS_NAME* class_name;
		Variable_class* variable_class;

		New* nw = rhs->value;

		class_name = dynamic_cast<CLASS_NAME*>(nw->class_name);
		variable_class = dynamic_cast<Variable_class*>(nw->class_name);

		// TODO: call the constructor (or pass the arguments for the constructor
		// to the various templates)
		if(class_name != NULL)
		{
			if(!agn->is_ref)
				INST (buf, "assign_expr_new", lhs->value, class_name);
			else
				INST (buf, "assign_expr_new_ref", lhs->value, class_name);
		}
		else if(variable_class != NULL)
		{
			VARIABLE_NAME* vcn = variable_class->variable_name;

			if(!agn->is_ref)
				INST (buf, "assign_expr_var_new", lhs->value, vcn);
			else
				INST (buf, "assign_expr_var_new_ref", lhs->value, vcn);
		}
		else
		{
			// Invalid class name type
			phc_unreachable();
		}

    // See comment in expr_method_invocation
		Object_list* params = new Object_list;
		foreach (Actual_parameter* ap, *rhs->value->actual_parameters)
		{
			params->push_back (ap->rvalue);
			if (ap->is_ref)
				ap->rvalue->attrs->set_true ("phc.codegen.is_ref");
		}


    INST (buf, "constructor_invocation",
      params,
      rhs->value->get_filename (),
      s(lexical_cast<string>(rhs->value->get_line_number())),
      s(lexical_cast<string>(rhs->value->actual_parameters->size())),
      lhs->value);
	}

protected:
	Wildcard<New>* rhs;
};

CREATE(Pattern_assign_expr_new);
